package oops.innerclasses;

public class CopyOfClassEnclosingAMethodWithAnonInnerClass {
	
	private int i = 100;
	private char ch = 'p';
	private String str = "ENCOSING-CLASS";
	
	interface ForAnonInnerClass {
		int implMe(int input);
	}
	
	public void foo(final int bar) {
		final int foosLocalVar = 200;
		System.out.println("foosLocalVar(a final one) = " + foosLocalVar);
		
		int output = callWithAnImplOfAnonInnerClass(new ForAnonInnerClass() {
			// Adds the parameter passed to the final local variable of this method 
			// and the (non-final)instance variable of this class
			@Override
			public int implMe(int input) {
				input = input + i; // Updates possible for method parameters; NEED NOT BE final
				updateStr("ANON-INNER-CLASS");
				i = input + foosLocalVar;
				return i;
				// NOTE: Fields of the class NEED NOT BE final
				// local variables / parameters of methods MUST BE final. Cannot be updated.
			}
		}, 300);
		System.out.println("Output: " + output + "\nFoosLocalVar(a final one): " + foosLocalVar);
	}
	
	private void updateStr(String str) {
		this.str = str;
	}
		
	private int callWithAnImplOfAnonInnerClass(ForAnonInnerClass faic, int input) {
		return faic.implMe(input);
	}
	
	public void printData() {
		System.out.println("\n\nDATA: "
				+ "i = " + i
				+ "\tch = " + ch
				+ "\tstr = " + str
		);
	}

	public static void main(String[] args) {
		CopyOfClassEnclosingAMethodWithAnonInnerClass cl = new CopyOfClassEnclosingAMethodWithAnonInnerClass();
		cl.printData();
		cl.foo(99);
		cl.printData();
	}

}
